package com.txby.alipay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeCancelModel;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;

/**
 * 支付宝交易处理
 * 
 * @ClassName: AlipayTradeUtil
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author jacking
 * @date 2017年10月30日 下午4:33:40
 *
 */
public class AlipayTradeUtil {
	
	private AlipayConfig alipayConfig;
	private String  notify_url;
	
	public AlipayTradeUtil() {
		alipayConfig =alipayConfig==null?new AlipayConfig():alipayConfig;
	};
	public AlipayTradeUtil(AlipayConfig alipayConfig) {
		this.alipayConfig=alipayConfig;
		this.notify_url=alipayConfig.getNotify_url();
	};
 
	/** 
	* @return ac 
	*/
	public AlipayConfig getAlipayConfig() {
		return alipayConfig;
	}
	/** 
	* @return notify_url 
	*/
	public String getNotify_url() {
		return notify_url;
	}
	/**
	 * 交易取消
	 * 支付交易返回失败或支付系统超时，调用该接口撤销交易。如果此订单用户支付失败，支付宝系统会将此订单关闭；如果用户支付成功，支付宝系统会将此订单资金退还给用户。
	 * 注意：只有发生支付系统超时或者支付结果未知时可调用撤销，其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】，没有明确的支付结果再调用【撤销订单API】。
	* @Title: alipayTradeCancel 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ac
	* @param @param outTradeNo
	* @param @return    设定文件 
	* @return JSONObject    返回类型 
	* @throws
	 */
	public JSONObject alipayTradeCancel(String outTradeNo) {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id,
					alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset,
					alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
			AlipayTradeCancelModel model = new AlipayTradeCancelModel();
			model.setOutTradeNo(outTradeNo);
			request.setBizModel(model);
			AlipayTradeCancelResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} 
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	
	/**
	 * 交易关闭
	 * 用于交易创建后，用户在一定时间内未进行支付，可调用该接口直接将未付款的交易进行关闭。
	* @Title: alipayTradeCancel 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ac
	* @param @param outTradeNo
	* @param @return    设定文件 
	* @return JSONObject    返回类型 
	* @throws
	 */
	public JSONObject alipayTradeClose(String outTradeNo) {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id,
					alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset,
					alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradeCloseRequest  request = new AlipayTradeCloseRequest();
			AlipayTradeCloseModel model = new AlipayTradeCloseModel();
			model.setOutTradeNo(outTradeNo);
			request.setBizModel(model);
			AlipayTradeCloseResponse  response = alipayClient.execute(request);
//			System.out.println(response.getBody());
			if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} 
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	/**
	(查询对账单下载地址)
	* @Title: alipayDataDataserviceBillDownloadurlQuery 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ac
	* @param @param billDate 账单时间：日账单格式为yyyy-MM-dd，月账单格式为yyyy-MM。
	* @param @return    设定文件 
	* @return JSONObject    返回类型 
	* @throws
	 */
	public  JSONObject alipayDataDataserviceBillDownloadurlQuery(String billDate)  {
		JSONObject json = null;
		try {
			
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayDataDataserviceBillDownloadurlQueryRequest request = 	new AlipayDataDataserviceBillDownloadurlQueryRequest();
			AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
			//账单时间：日账单格式为yyyy-MM-dd，月账单格式为yyyy-MM。
			model.setBillDate("2017-11");
			//账单类型，trade指商户基于支付宝交易收单的业务账单；signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单；
			model.setBillType("trade");
			request.setBizModel(model);
			AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
		 	if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} 
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	/**
	(统一收单交易退款接口)
	* @Title: alipayTradeRefund 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param  ac
	* @param outTradeNo 传入的商户订单号
	* @param refundAmount  需要退款的金额，该金额不能大于订单金额,单位为元，支持两位小数
	* @return JSONObject    返回类型 
	* @throws
	 */
	public  JSONObject alipayTradeRefund(String outTradeNo, String refundAmount)  {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
			AlipayTradeRefundModel model = new AlipayTradeRefundModel();
			//外部订单号
			model.setOutTradeNo(outTradeNo);
			//退款金额
			model.setRefundAmount(refundAmount);
			//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
			//model.setOutRequestNo("HZ01RF001");
			request.setBizModel(model);
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			json = JSON.parseObject(response.getBody());
	/*		if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} */
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	public  JSONObject alipayTradeRefund(AlipayTradeRefundModel model )  {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
			request.setBizModel(model);
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			json = JSON.parseObject(response.getBody());
			/*		if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} */
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	
	/**
	商家扫码收钱
	统一收单交易支付接口（条码支付）
	* @Title: alipayTradeRefund 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ac
	* @param @param outTradeNo  传入的商户订单号
	* @param @param totalAmount 金额
	* @param @param authCode 支付授权码，25~30开头的长度为16~24位的数字，实际字符串长度以开发者获取的付款码长度为准
	* @param @param subject 订单标题
	* @param @return    设定文件 
	* @return JSONObject    返回类型 
	* @throws
	 */
	public  JSONObject alipayTradePay(String outTradeNo, String totalAmount,String authCode,String subject)  {
		JSONObject json = null;
		try {
	        //获得初始化的AlipayClient
				AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
				//创建API对应的request类		
				AlipayTradePayRequest request = new AlipayTradePayRequest(); //创建API对应的request类 
				AlipayTradePayModel model = new AlipayTradePayModel();
				model.setOutTradeNo(outTradeNo);
				model.setScene("bar_code");
				//支付授权码，25~30开头的长度为16~24位的数字，实际字符串长度以开发者获取的付款码长度为准
				model.setAuthCode(authCode);
				//订单标题
				model.setSubject(subject);
				model.setTotalAmount(totalAmount);
				request.setBizModel(model);
//		         下面两代码是使用第三方应用授权传值方式
				/****************************授权传app_auth_token写法*********************
			
		          第三方应用授权获取app_auth_token可参照该贴：https://openclub.alipay.com/read.php?tid=1649&fid=43
		          获取app_auth_token
		          String app_auth_token="";
		          AlipayTradePayResponse response = alipayClient.execute(request,"",app_auth_token);
		      	 **/
			//通过alipayClient调用API，获得对应的response类			
			AlipayTradePayResponse response = alipayClient.execute(request);
			json = JSON.parseObject(response.getBody());
	/*		if(response.isSuccess()){
//				System.out.println("调用成功");
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} */
//			 System.out.println("地址：" + response.getBody());
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	 /**
	                用户二维码扫描支付
	  * alipay.trade.precreate (统一收单线下交易预创建)
	 * @Title: alipayTradePrecreate 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param @param ac
	* @param @param outTradeNo  传入的商户订单号 out_trade_no（订单号）必须是唯一的，测试一次必须修改新的订单号
	* @param @param totalAmount 金额
	* @param @param subject 订单标题
	 * @param @return    设定文件 
	 * @return JSONObject    返回类型 
	 * @throws
	  */
	public  JSONObject alipayTradePrecreate(String outTradeNo, String totalAmount,String subject)  {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
			request.setNotifyUrl(alipayConfig.getNotify_url());
			AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
			//out_trade_no（订单号）必须是唯一的，测试一次必须修改新的订单号
			model.setOutTradeNo(outTradeNo);
			model.setTotalAmount(totalAmount);
			model.setSubject(subject);
			request.setBizModel(model);
			
//			request.setBizContent("{\"out_trade_no\":\"201708091110333\", \"total_amount\":0.01,\"subject\":\"Iphone6 16G\"}");
			
			AlipayTradePrecreateResponse response =  alipayClient.execute(request);
			//条码支付详细信息
			//qr_Code当前预下单请求生成的二维码码串，可以用二维码生成工具根据该码串值生成对应的二维码
			json = JSON.parseObject(response.getBody());
	/*		if(response.isSuccess()){
				System.out.println("条码支付详细信息："+response.getBody());
				System.out.println("二维码码串："+response.getQrCode());
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} */
//			 System.out.println("地址：" + response.getBody());
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	/**
	 * app支付后端下单返回client信息进行支付
	* @Title: alipayTradeAppPay 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param outTradeNo
	* @param @param body 订单描述
	* @param @param totalAmount
	* @param @param subject 订单标题
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public JSONObject alipayTradeAppPay(String outTradeNo, String body, String totalAmount, String subject) {
		JSONObject json = null;
		try {
			// 实例化客户端
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id,
					alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset,
					alipayConfig.alipay_public_key, alipayConfig.sign_type);
			// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
			AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
			AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
			model.setBody(body == null ? "" : body);
			model.setSubject(subject);
			model.setOutTradeNo(outTradeNo);
			model.setTimeoutExpress("30m");
			model.setTotalAmount(totalAmount);
			model.setProductCode("QUICK_MSECURITY_PAY");
			request.setBizModel(model);
			request.setNotifyUrl(alipayConfig.getNotify_url());
			try {
				// 这里和普通的接口调用不同，使用的是sdkExecute
				AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
				System.out.println(response.getBody());// 就是orderString 可以直接给客户端请求，无需再做处理。
				json = JSON.parseObject(response.getBody());
			} catch (AlipayApiException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	/**
	alipay.trade.query (统一收单线下交易查询)
	 * 
	* @Title: alipayTradeQuery 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ac
	 @param @param outTradeNo  传入的商户订单号 out_trade_no（订单号）必须是唯一的，测试一次必须修改新的订单号
	* @param @return    设定文件 
	* @return JSONObject    返回类型 
	* @throws
	 */
	public  JSONObject alipayTradeQuery(String outTradeNo)  {
		JSONObject json = null;
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, alipayConfig.format, alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
			AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
			//out_trade_no（外部订单号）和trade_no（支付宝交易号)二选一用 即可查询
			AlipayTradeQueryModel model = new AlipayTradeQueryModel();
			model.setOutTradeNo(outTradeNo);
			//model.setTradeNo("2016113021001004950297103440");
			request.setBizModel(model);
			AlipayTradeQueryResponse response = alipayClient.execute(request);
//			System.out.println(response.getBody());
			json = JSON.parseObject(response.getBody());
		/*	if(response.isSuccess()){
				json = JSON.parseObject(response.getBody());
			} else {
//				System.out.println("调用失败");
			} */
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return json;
	}
	public static void main(String[] args) {
		AlipayTradeUtil at=new AlipayTradeUtil();
		AlipayConfig ac=new  AlipayConfig();
//		String outTradeNo=System.currentTimeMillis()+"";
		  String out_trade_no="5774104441513258686946";
//		  System.out.println("订单号："+outTradeNo);
/*   JSONObject jo=  at.alipayTradePrecreate(out_trade_no, "0.01", "华硕电脑");
		  System.out.println(jo);
		  jo=jo.getJSONObject("alipay_trade_precreate_response");
		System.out.println("支付二维码:"+jo.get("qr_code")); */
//		System.out.println(at.alipayTradeCancel(out_trade_no));
//			System.out.println(at.alipayTradeCancel(out_trade_no));
//		System.out.println(at.alipayTradeQuery(out_trade_no));
//		System.out.println(at.alipayTradeCancel(out_trade_no));
//		at.alipayTradeCancel(out_trade_no);
	
//		System.out.println(	at.alipayTradeQuery(ac, out_trade_no).get("alipay_trade_query_response"));*/
		
/*		  JSONObject jo=  at.alipayTradePrecreate(out_trade_no, "0.10", "华硕电脑");
		  System.out.println(jo);
		  jo=jo.getJSONObject("alipay_trade_precreate_response");
		System.out.println("支付二维码:"+jo.get("qr_code"));*/
		/*System.out.println(at.alipayTradeClose(out_trade_no));
		System.out.println(at.alipayTradeQuery(out_trade_no));*/
//		
		  
		 
			//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
			//model.setOutRequestNo("HZ01RF001");
			//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
			//model.setOutRequestNo("HZ01RF001");
		  
		  AlipayTradeRefundModel model = new AlipayTradeRefundModel();
			//外部订单号
			model.setOutTradeNo(out_trade_no);
			//退款金额
			model.setRefundAmount("0.01");
			//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。
			model.setOutRequestNo("HZ01RF001");
//		System.out.println(	at.alipayTradeRefund("5774104441513258686946", "0.01"));
		System.out.println(	at.alipayTradeRefund(model));
		
		
	}

}
